﻿// Decompiled with JetBrains decompiler
// Type: TaleWorlds.CampaignSystem.LogEntries.PlayerBattleEndedLogEntry
// Assembly: TaleWorlds.CampaignSystem, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
// MVID: E85F8C15-4DF6-4E9C-A58A-29177E40D07A
// Assembly location: D:\steam\steamapps\common\Mount & Blade II Bannerlord\bin\Win64_Shipping_Client\TaleWorlds.CampaignSystem.dll

using Helpers;
using System.Collections.Generic;
using TaleWorlds.CampaignSystem.CharacterDevelopment;
using TaleWorlds.CampaignSystem.Conversation;
using TaleWorlds.CampaignSystem.Encounters;
using TaleWorlds.CampaignSystem.MapEvents;
using TaleWorlds.CampaignSystem.Party;
using TaleWorlds.CampaignSystem.Roster;
using TaleWorlds.CampaignSystem.Settlements;
using TaleWorlds.Core;
using TaleWorlds.Library;
using TaleWorlds.Localization;
using TaleWorlds.SaveSystem;

#nullable disable
namespace TaleWorlds.CampaignSystem.LogEntries
{
  public class PlayerBattleEndedLogEntry : LogEntry, IChatNotification
  {
    [SaveableField(280)]
    private readonly Hero _winnerSideHero;
    [SaveableField(281)]
    private readonly Hero _defeatedSideHero;
    [SaveableField(282)]
    private readonly Clan _defeatedSideClan;
    [SaveableField(283)]
    private readonly Clan _winnerSideClan;
    [SaveableField(284)]
    private readonly TextObject _defeatedSidePartyName;
    [SaveableField(285)]
    private readonly bool _defeatedSidePartyIsSettlement;
    [SaveableField(286)]
    private readonly bool _defeatedSidePartyIsBanditFaction;
    [SaveableField(287)]
    private readonly MBReadOnlyDictionary<Hero, short> _witnesses;
    [SaveableField(288)]
    private readonly bool _isAgainstGreatOdds;
    [SaveableField(289)]
    private readonly bool _isEasyPlayerVictory;
    [SaveableField(290)]
    private readonly bool _isPlayerLastStand;
    [SaveableField(291)]
    private readonly bool _isAgainstCaravan;
    [SaveableField(292)]
    private readonly bool _playerVictory;
    [SaveableField(293)]
    private readonly bool _playerWasAttacker;
    [SaveableField(294)]
    private readonly Settlement _capturedSettlement;

    internal static void AutoGeneratedStaticCollectObjectsPlayerBattleEndedLogEntry(
      object o,
      List<object> collectedObjects)
    {
      ((LogEntry) o).AutoGeneratedInstanceCollectObjects(collectedObjects);
    }

    protected override void AutoGeneratedInstanceCollectObjects(List<object> collectedObjects)
    {
      base.AutoGeneratedInstanceCollectObjects(collectedObjects);
      collectedObjects.Add((object) this._winnerSideHero);
      collectedObjects.Add((object) this._defeatedSideHero);
      collectedObjects.Add((object) this._defeatedSideClan);
      collectedObjects.Add((object) this._winnerSideClan);
      collectedObjects.Add((object) this._defeatedSidePartyName);
      collectedObjects.Add((object) this._witnesses);
      collectedObjects.Add((object) this._capturedSettlement);
    }

    internal static object AutoGeneratedGetMemberValue_winnerSideHero(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._winnerSideHero;
    }

    internal static object AutoGeneratedGetMemberValue_defeatedSideHero(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._defeatedSideHero;
    }

    internal static object AutoGeneratedGetMemberValue_defeatedSideClan(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._defeatedSideClan;
    }

    internal static object AutoGeneratedGetMemberValue_winnerSideClan(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._winnerSideClan;
    }

    internal static object AutoGeneratedGetMemberValue_defeatedSidePartyName(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._defeatedSidePartyName;
    }

    internal static object AutoGeneratedGetMemberValue_defeatedSidePartyIsSettlement(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._defeatedSidePartyIsSettlement;
    }

    internal static object AutoGeneratedGetMemberValue_defeatedSidePartyIsBanditFaction(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._defeatedSidePartyIsBanditFaction;
    }

    internal static object AutoGeneratedGetMemberValue_witnesses(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._witnesses;
    }

    internal static object AutoGeneratedGetMemberValue_isAgainstGreatOdds(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._isAgainstGreatOdds;
    }

    internal static object AutoGeneratedGetMemberValue_isEasyPlayerVictory(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._isEasyPlayerVictory;
    }

    internal static object AutoGeneratedGetMemberValue_isPlayerLastStand(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._isPlayerLastStand;
    }

    internal static object AutoGeneratedGetMemberValue_isAgainstCaravan(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._isAgainstCaravan;
    }

    internal static object AutoGeneratedGetMemberValue_playerVictory(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._playerVictory;
    }

    internal static object AutoGeneratedGetMemberValue_playerWasAttacker(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._playerWasAttacker;
    }

    internal static object AutoGeneratedGetMemberValue_capturedSettlement(object o)
    {
      return (object) ((PlayerBattleEndedLogEntry) o)._capturedSettlement;
    }

    public bool IsVisibleNotification
    {
      get => this._defeatedSideHero != null && this._winnerSideHero != null;
    }

    public PlayerBattleEndedLogEntry(MapEvent mapEvent)
    {
      PartyBase leaderParty1 = (mapEvent.BattleState == BattleState.AttackerVictory ? mapEvent.AttackerSide : mapEvent.DefenderSide).LeaderParty;
      PartyBase leaderParty2 = mapEvent.GetMapEventSide(mapEvent.DefeatedSide).LeaderParty;
      this._winnerSideHero = leaderParty1.LeaderHero;
      this._defeatedSideHero = leaderParty2.LeaderHero;
      this._defeatedSidePartyIsSettlement = leaderParty2.IsSettlement && (leaderParty2.Settlement.IsTown || leaderParty2.Settlement.IsCastle);
      if (this._defeatedSidePartyIsSettlement)
        this._capturedSettlement = leaderParty2.Settlement;
      this._defeatedSidePartyIsBanditFaction = leaderParty2.MapFaction.IsBanditFaction;
      this._defeatedSidePartyName = leaderParty2.Name;
      this._winnerSideClan = this.GetClanOf(leaderParty1);
      this._defeatedSideClan = this.GetClanOf(leaderParty2);
      BattleSideEnum playerSide = PlayerEncounter.Current.PlayerSide;
      MapEventSide mapEventSide1 = mapEvent.GetMapEventSide(playerSide);
      MapEventSide mapEventSide2 = mapEvent.GetMapEventSide(playerSide.GetOppositeSide());
      float strengthRatio = mapEventSide1.StrengthRatio;
      int casualties1 = mapEventSide1.Casualties;
      int casualties2 = mapEventSide2.Casualties;
      this._playerVictory = playerSide == mapEvent.WinningSide;
      this._playerWasAttacker = playerSide == mapEvent.AttackerSide.MissionSide;
      this._isAgainstGreatOdds = (double) strengthRatio > 1.5;
      this._isEasyPlayerVictory = (double) strengthRatio < 0.5 && casualties1 * 3 < casualties2 && playerSide == mapEvent.WinningSide;
      if (this._defeatedSidePartyIsSettlement)
        this._isEasyPlayerVictory = (double) strengthRatio < 0.25 && casualties1 * 3 < casualties2 && playerSide == mapEvent.WinningSide;
      this._isPlayerLastStand = playerSide == mapEvent.DefeatedSide && casualties2 > casualties1;
      MobileParty mobileParty = mapEventSide2.Parties[0].Party.MobileParty;
      this._isAgainstCaravan = playerSide == mapEvent.WinningSide && mobileParty != null && mobileParty.IsCaravan;
      Dictionary<Hero, short> dictionary = new Dictionary<Hero, short>();
      if (mapEvent != null)
      {
        foreach (PartyBase involvedParty in mapEvent.InvolvedParties)
        {
          foreach (TroopRosterElement troopRosterElement in (List<TroopRosterElement>) involvedParty.MemberRoster.GetTroopRoster())
          {
            if (troopRosterElement.Character.HeroObject != null && !dictionary.ContainsKey(troopRosterElement.Character.HeroObject))
              dictionary.Add(troopRosterElement.Character.HeroObject, involvedParty.Side == MobileParty.MainParty.Party.Side ? (short) 1 : (short) -1);
          }
        }
      }
      this._witnesses = dictionary.GetReadOnlyDictionary<Hero, short>();
    }

    private Clan GetClanOf(PartyBase party)
    {
      if (party.MobileParty?.ActualClan != null)
        return party.MobileParty.ActualClan;
      if (party.Owner != null)
        return !party.Owner.IsNotable ? party.Owner.Clan : party.Owner.HomeSettlement.OwnerClan;
      if (party.IsSettlement)
        return party.Settlement.OwnerClan;
      return party.LeaderHero != null ? party.LeaderHero.Clan : (Clan) null;
    }

    public override ImportanceEnum GetImportanceForClan(Clan clan) => ImportanceEnum.Zero;

    public override void GetConversationScoreAndComment(
      Hero talkTroop,
      bool findString,
      out string comment,
      out ImportanceEnum score)
    {
      short num1;
      if (!this._witnesses.TryGetValue(talkTroop, out num1))
        num1 = (short) -2;
      score = ImportanceEnum.Zero;
      comment = "";
      bool flag = this._winnerSideHero == Hero.MainHero;
      if (this._playerVictory)
      {
        if (this._capturedSettlement != null)
        {
          if (Hero.MainHero.CurrentSettlement == this._capturedSettlement && Hero.OneToOneConversationHero.IsNotable)
          {
            score = ImportanceEnum.QuiteImportant;
            comment = "str_comment_endplayerbattle_you_stormed_this_city";
          }
          else if (num1 == (short) 1)
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            MBTextManager.SetTextVariable("ENEMY_SETTLEMENT", this._defeatedSidePartyName, false);
            if (this._isEasyPlayerVictory)
              comment = "str_comment_endplayerbattle_we_stormed_castle_easy";
            else
              comment = "str_comment_endplayerbattle_we_stormed_castle";
          }
          else if (flag && this._defeatedSideClan == talkTroop.Clan)
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            MBTextManager.SetTextVariable("SETTLEMENT_NAME", this._defeatedSidePartyName, false);
            comment = "str_comment_endplayerbattle_you_captured_our_castle";
          }
          else
          {
            if (!flag)
              return;
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            MBTextManager.SetTextVariable("SETTLEMENT_NAME", this._defeatedSidePartyName, false);
            comment = "str_comment_endplayerbattle_you_stormed_castle";
          }
        }
        else if (((this._defeatedSideHero == null ? 0 : (this._defeatedSideHero == talkTroop ? 1 : 0)) & (flag ? 1 : 0)) != 0)
        {
          score = ImportanceEnum.SomewhatImportant;
          if (!findString)
            return;
          comment = "str_comment_endplayerbattle_you_defeated_me";
        }
        else if (this._defeatedSideHero != null && num1 == (short) 1 && talkTroop.MapFaction == Hero.MainHero.MapFaction && this._defeatedSideHero.MapFaction != Hero.MainHero.MapFaction)
        {
          score = ImportanceEnum.SomewhatImportant;
          if (!findString)
            return;
          MBTextManager.SetTextVariable("ENEMY_TERM", FactionHelper.GetTermUsedByOtherFaction(this._defeatedSideHero.MapFaction, (IFaction) talkTroop.Clan, false), false);
          MBTextManager.SetTextVariable("DEFEATED_PARTY_LEADER", this._defeatedSideHero.Name, false);
          comment = "str_comment_endplayerbattle_we_defeated_enemy";
        }
        else if (this._defeatedSidePartyIsBanditFaction)
        {
          if (num1 == (short) 1 && this._isEasyPlayerVictory)
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            comment = "str_comment_endplayerbattle_we_hunted_bandit_easy";
          }
          else if (num1 == (short) 1)
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            comment = "str_comment_endplayerbattle_we_hunted_bandit";
          }
          else
          {
            if (!talkTroop.IsMerchant)
              return;
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            comment = "str_comment_endplayerbattle_you_hunted_bandit_merchant";
          }
        }
        else if (this._isAgainstCaravan)
        {
          if (this._defeatedSideClan == null || this._defeatedSideClan.Leader != talkTroop)
            return;
          score = ImportanceEnum.SomewhatImportant;
          if (!findString)
            return;
          comment = "str_comment_endplayerbattle_you_accosted_my_caravan";
        }
        else if (((this._defeatedSideHero == null || (this._defeatedSideClan.Kingdom == null ? (IFaction) this._defeatedSideClan : (IFaction) this._defeatedSideClan.Kingdom) != talkTroop.MapFaction ? 0 : (Hero.MainHero.MapFaction != talkTroop.MapFaction ? 1 : 0)) & (flag ? 1 : 0)) != 0)
        {
          int num2 = -5 - talkTroop.CharacterObject.GetTraitLevel(DefaultTraits.Mercy) * 5 - talkTroop.CharacterObject.GetTraitLevel(DefaultTraits.Generosity) * 5;
          if (talkTroop.GetRelation(this._defeatedSideHero) < num2)
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            MBTextManager.SetTextVariable("DEFEATED_LEADER_RELATIONSHIP", ConversationHelper.HeroRefersToHero(talkTroop, this._defeatedSideHero, true), false);
            this._defeatedSideHero.SetTextVariables();
            MBTextManager.SetTextVariable("DEFEATED_LEADER", this._defeatedSideHero.Name, false);
            comment = "str_comment_endplayerbattle_you_defeated_my_ally_disrespectful";
          }
          else
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            MBTextManager.SetTextVariable("DEFEATED_LEADER_RELATIONSHIP", ConversationHelper.HeroRefersToHero(talkTroop, this._defeatedSideHero, true), false);
            this._defeatedSideHero.SetTextVariables();
            MBTextManager.SetTextVariable("DEFEATED_LEADER", this._defeatedSideHero.Name, false);
            comment = "str_comment_endplayerbattle_you_defeated_my_ally";
          }
        }
        else
        {
          if (((this._defeatedSideHero == null || talkTroop.MapFaction != Hero.MainHero.MapFaction ? 0 : (FactionManager.IsAtWarAgainstFaction(this._defeatedSideClan.Kingdom == null ? (IFaction) this._defeatedSideClan : (IFaction) this._defeatedSideClan.Kingdom, talkTroop.MapFaction) ? 1 : 0)) & (flag ? 1 : 0)) == 0)
            return;
          if (this._isAgainstGreatOdds)
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            MBTextManager.SetTextVariable("DEFEATED_PARTY_LEADER", this._defeatedSideHero.Name, false);
            this._defeatedSideHero.SetTextVariables();
            comment = "str_comment_endplayerbattle_you_defeated_our_enemy_great_battle";
          }
          else
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            MBTextManager.SetTextVariable("DEFEATED_PARTY_LEADER", this._defeatedSideHero.Name, false);
            this._defeatedSideHero.SetTextVariables();
            comment = "str_comment_endplayerbattle_you_defeated_our_enemy";
          }
        }
      }
      else
      {
        if (this._playerVictory)
          return;
        if (this._winnerSideHero == talkTroop & flag)
        {
          score = ImportanceEnum.SomewhatImportant;
          if (!findString)
            return;
          comment = "str_comment_endplayerbattle_i_defeated_you";
        }
        else if (this._winnerSideHero == talkTroop && num1 == (short) -1)
        {
          score = ImportanceEnum.SomewhatImportant;
          if (!findString)
            return;
          comment = "str_comment_endplayerbattle_we_defeated_you";
        }
        else
        {
          if (!(this._winnerSideHero != null & flag))
            return;
          if ((((this._winnerSideClan.Kingdom == null ? (IFaction) this._winnerSideClan : (IFaction) this._winnerSideClan.Kingdom) != talkTroop.MapFaction ? 0 : (talkTroop.MapFaction != Hero.MainHero.MapFaction ? 1 : 0)) & (flag ? 1 : 0)) != 0)
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            MBTextManager.SetTextVariable("VICTORIOUS_PARTY_LEADER", this._winnerSideHero.Name, false);
            comment = "str_comment_endplayerbattle_my_ally_defeated_you";
          }
          else if (num1 == (short) 1 && this._winnerSideHero.MapFaction != Hero.MainHero.MapFaction && talkTroop.MapFaction == Hero.MainHero.MapFaction)
          {
            score = ImportanceEnum.SomewhatImportant;
            if (!findString)
              return;
            MBTextManager.SetTextVariable("VICTORIOUS_PARTY_LEADER", this._winnerSideHero.Name, false);
            MBTextManager.SetTextVariable("ENEMY_TERM", FactionHelper.GetTermUsedByOtherFaction(this._winnerSideHero.MapFaction, talkTroop.MapFaction, false), false);
            comment = "str_comment_endplayerbattle_we_were_defeated";
          }
          else
          {
            if (((talkTroop.MapFaction != Hero.MainHero.MapFaction ? 0 : (FactionManager.IsAtWarAgainstFaction(talkTroop.MapFaction, this._winnerSideClan.Kingdom == null ? (IFaction) this._winnerSideClan : (IFaction) this._winnerSideClan.Kingdom) ? 1 : 0)) & (flag ? 1 : 0)) == 0)
              return;
            if (this._isPlayerLastStand)
            {
              score = ImportanceEnum.SomewhatImportant;
              if (!findString)
                return;
              MBTextManager.SetTextVariable("VICTORIOUS_PARTY_LEADER", this._winnerSideHero.Name, false);
              MBTextManager.SetTextVariable("ENEMY_TERM", FactionHelper.GetTermUsedByOtherFaction(this._winnerSideHero.MapFaction, talkTroop.MapFaction, false), false);
              comment = "str_comment_endplayerbattle_our_enemy_defeated_you_pyrrhic";
            }
            else
            {
              score = ImportanceEnum.SomewhatImportant;
              if (!findString)
                return;
              MBTextManager.SetTextVariable("VICTORIOUS_PARTY_LEADER", this._winnerSideHero.Name, false);
              MBTextManager.SetTextVariable("ENEMY_TERM", FactionHelper.GetTermUsedByOtherFaction(this._winnerSideHero.MapFaction, talkTroop.MapFaction, false), false);
              comment = "str_comment_endplayerbattle_our_enemy_defeated_you";
            }
          }
        }
      }
    }

    public override string ToString() => this.GetNotificationText().ToString();

    public TextObject GetNotificationText()
    {
      TextObject parent = TextObject.Empty;
      if (this._winnerSideHero != null && this._defeatedSideHero != null)
      {
        parent = GameTexts.FindText("str_destroy_player_party");
        StringHelpers.SetCharacterProperties("HERO_1", this._winnerSideHero.CharacterObject, parent);
        StringHelpers.SetCharacterProperties("HERO_2", this._defeatedSideHero.CharacterObject, parent);
      }
      return parent;
    }
  }
}
